﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using YAPL.Language.Core.Exceptions;

namespace YAPL.Language.Core.Types {
	public class YAPLInt : YAPLObject {
		private int _intValue;
		public YAPLInt(int intValue)
			: base("YAPLInt") {
			_intValue = intValue;
		}

		public int IntValue {
			get { return _intValue; }
			set { _intValue = value; }
		}

		public override string ToString() {
			return IntValue.ToString();
		}

		public override object Value {
			get {
				return _intValue;
			}
		}
		#region operator overrides
		public override YAPLObject Add(YAPLObject other) {
			if (other is YAPLInt) {
				var otherValue = (other as YAPLInt).IntValue;
				return new YAPLInt(IntValue + otherValue);
			}
			if (other is YAPLFloat) {
				var otherValue = (other as YAPLFloat).FloatValue;
				return new YAPLFloat(IntValue + otherValue);
			}
			if (other is YAPLString) {
				var strValue = (other as YAPLString).StrValue;
				return new YAPLString(IntValue + strValue);
			}
			return base.Add(other);
		}

		public override YAPLObject Subtract(YAPLObject other) {
			if (other is YAPLInt) {
				var otherValue = (other as YAPLInt).IntValue;
				return new YAPLInt(IntValue - otherValue);
			}
			if (other is YAPLFloat) {
				var otherValue = (other as YAPLFloat).FloatValue;
				return new YAPLFloat(IntValue - otherValue);
			}
			return base.Add(other);
		}

		public override YAPLObject Multiply(YAPLObject other) {
			if (other is YAPLInt) {
				var otherValue = (other as YAPLInt).IntValue;
				return new YAPLInt(IntValue * otherValue);
			}
			if (other is YAPLFloat) {
				var otherValue = (other as YAPLFloat).FloatValue;
				return new YAPLFloat(IntValue * otherValue);
			}
			return base.Add(other);
		}

		public override YAPLObject Divide(YAPLObject other) {
			if (other is YAPLInt) {
				var otherValue = (other as YAPLInt).IntValue;
				return new YAPLInt(IntValue / otherValue);
			}
			if (other is YAPLFloat) {
				var otherValue = (other as YAPLFloat).FloatValue;
				return new YAPLFloat(IntValue / otherValue);
			}
			return base.Add(other);
		}

		public override YAPLObject Mod(YAPLObject other) {
			if (other is YAPLInt) {
				var otherValue = (other as YAPLInt).IntValue;
				return new YAPLInt(IntValue % otherValue);
			}
			return base.Add(other);
		}

		public override YAPLObject UnaryMinus() {
			return new YAPLInt(-IntValue);
		}

		public override YAPLObject UnaryPlus() {
			return new YAPLInt(+IntValue);
		}

		public override YAPLObject Increment() {
			IntValue += 1;
			return this;
		}

		public override YAPLObject Decrement() {
			IntValue -= 1;
			return this;
		}

		#endregion
	}
}
